#include <iostream>
#include <unistd.h>
#include <thread>

void thread_run()
{
    while(true)
    {
        std::cout<<"我是新线程..."<<std::endl;
        sleep(1);
    }
}

int main()
{
    // 任何语言，在linux中如果要实现多线程，必定要使用pthread库
    // 如何看待C++11中的多线程呢？？C++11 的多线程，在linux环境，本质是对pthread库的封装！（为什么pthread叫做原生线程库？原因就在这里）
    //如果编译时没有-lpthread选项，下面这份代码也是跑不起来的
    std::thread t1(thread_run);

    while(true)
    {
        std::cout<<"我是主线程..."<<std::endl;
        sleep(1);
    }

    t1.join();

    return 0;
}


// #include <iostream>
// #include <string>
// #include <vector>
// #include <cstdio>
// #include <cassert>
// #include <pthread.h>
// #include <unistd.h>

// using namespace std;

// //当成结构体使用
// class ThreadData
// {
// public:
//     int number;//线程的编号
//     pthread_t tid;
//     char namebuffer[64];
// };
// class ThreadReturn 
// {
// public:
//     int exit_code;
//     int exit_result;
// };

// //问题1: start_routine，现在是被几个线程执行呢？10个，现在这个函数是什么状态？重入状态
// //问题2: 该函数是可重入函数吗？是的！
// //3. 在函数内定义的变量都是局部变量，具有临时性 -- 今天依旧适用 -- 在多线程情况下，也没有问题 -- 其实每一个线程都有自己独立的栈结构
// void *start_routine(void *args)// start_routine-->线程执行的历程
// {
//     sleep(1);

//     // string name = static_cast<const char*>(args);// 一种安全的强制类型转换，明确告诉编译器我们就是要进行强转，而不是由于疏忽导致的隐式强转
//     ThreadData *td = static_cast<ThreadData *>(args);
//     int cnt = 10;
//     while(cnt)
//     {
//         // cout<<"cnt: "<<cnt<<" &cnt "<<&cnt<<endl;//每个线程的cnt的地址都是不一样的
//         // cnt--;


//         // sleep(1);
//         // exit(0);//任何一个执行流调用exit都会让整个进程退出。

//         // pthread_exit(nullptr);
//         // return nullptr;

//         cout << "new thread create success, name: " << td->namebuffer << " cnt: " << cnt-- << endl;
//         sleep(1);
//         // int *p = nullptr;
//         // *p = 10;
//     }
//     //线程如何终止的问题？1.pthread_exit 2.return 
//     // delete td;

//     // return nullptr;// 终止方法1: 线程函数运行结束，return的时候，线程就算终止了
//     // pthread_exit(nullptr);
//     // return (void *)td->number;// 有warning，但不影响 void *ret = (void *)td->number; 相当于直接把整型数字写到ret这个指针变量指向的空间里面
//     //原先返回的变量里面保存的是某个字面值，现在返回的变量里面保存的是地址。

//     // pthread_exit((void*)106);//return和pthread_exit 线程退出后的信息会被pthread_join拿到

//     ThreadReturn *tr = new ThreadReturn;
//     tr->exit_code = 1;
//     tr->exit_result = 106;
    
//     // ThreadReturn tr; 
//     // return &tr;//不能这么做！因为在栈上开辟的空间，出了函数栈帧后会被销毁，地址会变为野指针！

//     // return (void*)tr;//指针变量tr在这里，作的是右值。
//     return (void*)100;
// }
// int main()
// {
//     // 1.我们想创建一批线程
//     vector<ThreadData*> threads;
// #define NUM 10
//     for(int i = 0; i < NUM; i++)
//     {
//         ThreadData* td = new ThreadData;
//         td->number = i+1;
//         snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);
//         pthread_create(&td->tid, nullptr, start_routine, td);
//         threads.push_back(td);


//         // pthread_t tid;
//         // char namebuffer[64];
//         // snprintf(namebuffer, sizeof(namebuffer), "%s:%d", "thread", i);
//         // pthread_create(&tid, nullptr, start_routine, namebuffer);//传过去的是缓冲区的起始地址
//         // sleep(1);
//     }

//     for(auto &it : threads)
//     {
//         cout<< "create thread" << it->namebuffer << " : "<< it->tid << " success" << endl;
//     }

//     // 线程是可以被cancel的，例如主线程cancel新线程。 注意: 线程要被取消，前提是这个线程已经跑起来了
//     // 线程如果是被取消的，退出码是(void*)-1，对应一个宏 PTHREAD_CANCELED; -> #define PTHREAD_CANCELED ((void *) -1)
    
//     sleep(5);
//     for(int i = 0; i < threads.size()/2; i++)// 取消一半的线程
//     {
//         pthread_cancel(threads[i]->tid);
//         cout << "pthread cancel : " << threads[i]->namebuffer << " success " << endl;
//     }
//     sleep(1);
//     for(auto &it : threads)
//     {
//         void *ret = nullptr;// 线程函数的返回值，会放到我们定义的ret指针变量里面！
//         // ThreadReturn* ret = nullptr;
//         int n = pthread_join(it->tid, (void**)&ret);
//         // void** retp; *retp = return (void *)td->number; //pthread_join内部实现的伪代码
//         //等待过后，ret里面存储的就不是空了，而是线程函数返回的(void*)number，线程函数的返回值是通过pthread_join的第二个输出型参数拿回来的！

//         assert(n == 0);
//         cout<<"join : "<<it->namebuffer<<" success , exit_code: "<< (long long)ret << endl;
//         // cout<<"join : "<<it->namebuffer<<" success , exit_code: "<< ret->exit_code << ", exit_result : " << ret->exit_result << endl;
//         delete it;//在主线程统一申请每个线程的ThreadData结构体，并且进行统一释放。
//     }
//     cout<<"main thread quit"<<endl;




//     // while(true)
//     // {
//     //     cout << "new thread create success, name: main thread" << endl;
//     //     sleep(1);
//     // }


//     // pthread_t tid;
//     // pthread_create(&tid, nullptr, start_routine, (void *)"thread new");

//     // while(true)
//     // {
//     //     cout << "new thread create success, name: main thread" << endl;
//     //     sleep(1);
//     // }


//     return 0;
// }